package com.hrpc.loadbalancer;

import com.hrpc.discovery.Register;
import com.hrpc.hRpcBootStarp;
import com.hrpc.loadbalancer.impl.RoundRobinLoadBalancer;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractLoadBalancer implements LoadBalancer{
    //一个服务会匹配一个selector
    private Map<String, Selector> cache=new ConcurrentHashMap<>(8);
    @Override
    public InetSocketAddress selectServerAddress(String serviceName,String group) {
        //1.优先从cache中获取一个选择器
        Selector selector = cache.get(serviceName);
        //2.如果没有就需要为这个service创建一个selector，并将它放到缓存中
        if (selector == null){
            // 对于这个负载均衡器，内部应该维护服务列表作为缓存
            List<InetSocketAddress> serviceList = hRpcBootStarp.getInstance().getRegister().lookup(serviceName,group);
            // 提供一些算法负载选取合适的节点
            selector=getSelector(serviceList);
            //放入缓存中
            cache.put(serviceName,selector);
        }
        //获取可用节点
        return selector.getNext();
    }
    /**
     * 由子类进行扩展
     * @param serviceList 服务列表
     * @return 负载均衡算法选择器
     */
    protected abstract Selector getSelector(List<InetSocketAddress> serviceList);

    @Override
    public synchronized void reLoadBalance(String serviceName,List<InetSocketAddress> addresses) {
        //我们可以根据新的服务列表生成新的selector
        cache.put(serviceName,getSelector(addresses));
    }
}
